import java.io.IOException;
import java.net.ServerSocket;

import org.apache.log4j.Appender;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Logger;
import org.springframework.context.support.ClassPathXmlApplicationContext;

//Zuo
public class ServerSchedule {
	private static Logger logger1 = Logger.getLogger("quartz");
	private static Logger logger2 = Logger.getLogger("mode");

	// 检查 端口开启
	private static boolean is_port_open = false;
	// 监控端口号
	private static int port = 3444;

	// 备用项目监控端口
	private static int slave_port;
	private static boolean is_slave_port_open = false;
	// 模式
	private static int mode;
	// 等待时间 s为单位
	private static int sleep_time = 10;

	static ServerSocket socket;

	private static String log_path = null;

	// ServerSocket s=new ServerSocket(port);
	private static long threadName = System.currentTimeMillis();

	public static void startServer(String[] args) {
		// 查看参数
		if (args.length > 0) {
			if (args[0].equalsIgnoreCase("help")) {
				printHelp();
				return;
			} else {
				handlePara(args);
			}
			// user's setting
			execute();
		} else {
			// default setting
			handleLog(args);
			handleMode(port);
			execute();
		}
	}

	private static void execute() {

		// 运行程序
		if (is_port_open || is_slave_port_open) {
			runApp();
		} else {
			System.out.println("The Master port [ " + port + " ] and the Slave port [ " + slave_port
					+ " is Already in use,please check...");
		}
	}

	// 开启端口,true 成功 false失败
	private static boolean openPort(int port) {
		try {
			socket = new ServerSocket(port);
			return true;
			// is_port_open = true;
		} catch (IOException e) {
			return false;
		}
	}

	private static void handlePara(String[] args) {
		handleLog(args);
		handlePort(args);
		handleMode(port);
		handleTime(args);
	}

	// 系统模式选择
	private static void handleMode(int port2) {
		slave_port = getSlave_port();
		// 打开端口成功
		if (openPort(port2)) {
			logger2.info("Thread " + threadName + " Enter Master Mode ------");
			mode = 1;
			is_port_open = true;
		} else {
			// 打开端口失败，非主模式
			if (openPort(slave_port)) {
				// 打开备用端口成功
				logger2.info("Thread " + threadName + " Enter Slave Mode ------");
				mode = 2;
				is_slave_port_open = true;
			} else {
				System.out.println("The Master Port And Slave Port is in Use... please check...");
				mode = 3;
			}

		}

	}

	// 关闭虚拟机
	private static void shutdownService() {
		System.exit(0);
	}

	// 打印帮助信息
	private static void printHelp() {
		System.out.println("-------------------arguments instructions-------------------------");
		System.out.println("log=logpath		//\t configure your log path ...");
		System.out.println("port=port      	        //\t point the listened port .the default port is : 3444");
		System.out.println("internal=internal        // \t default internal is 10seconds");
		System.out.println("\n\nTips:please strictly identified your parameter syntax");
		System.out.println("-------------------end------------------------------------------------");
	}

	// 运行定时器主程序
	private static void runApp() {
		// use default settings ...
		if (mode == 1) {
			// Master Mode
			System.out.println("##############定时任务开启##################");
			new ClassPathXmlApplicationContext("classpath:application-persist-for-quartz.xml");
			String logpath = log_path == null ? "项目中默认位置  " : log_path;
			System.out.println("日志路径位   [  " + logpath + "]");
			System.out.println("开启了对端口[ " + port + " ]的监听");
			System.out.println("##############定时任务运行中#################");
		} else if (mode == 2) {
			// Slave Mode
			listenMasterPort(port);
		}
	}

	private static void listenMasterPort(int port2) {
		// TODO Auto-generated method stub
		while (!is_port_open) {
			try {
				Thread.sleep(sleep_time * 1000);
				logger2.info("Thread " + threadName + " Master is alive, i am in Slave mode ---");
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			if (openPort(port)) {
				logger2.info("Thread " + threadName + " Enter Master Mode ------");
				is_port_open = true;
				is_slave_port_open = false;
				mode = 1;
				// 进入主模式就开启应用
				runApp();
			}

		}
	}

	// 设置监听端口
	private static void handlePort(String[] args) {
		String _tmp_port = checkPara(args, "port");
		if (null != _tmp_port) {
			String _port = getPara(_tmp_port);
			try {
				port = Integer.parseInt(_port);
			} catch (NumberFormatException e) {
				port = 3444;
			}
		}
	}

	// 修改日志目录
	private static void handleLog(String[] args) {
		setModeLogPath();
		String _tmp_logpath = checkPara(args, "log");
		if (null != _tmp_logpath) {
			setLogPath(_tmp_logpath);
			log_path = _tmp_logpath;
		}
	}

	// 设置监听时间间隔
	private static void handleTime(String[] args) {
		String _time = checkPara(args, "internal");
		if (null != _time) {
			try {
				sleep_time = Integer.parseInt(_time);
			} catch (NumberFormatException e) {
				sleep_time = 10;
			}
		}
	}

	// 获取指定参数 1.所有参数 2.指定参数
	private static String checkPara(String[] para, String pointPara) {
		for (int i = 0; i < para.length; i++) {
			if (para[i].startsWith(pointPara)) {
				return para[i];
			}
		}
		return null;
	}

	// 获取参数对应的值
	private static String getPara(String para) {
		return para.substring(para.indexOf("=") + 1);
	}

	// 设置用户指定日志路径
	private static void setLogPath(String log) {
		Appender appender = logger1.getAppender("quartz");
		if (appender instanceof FileAppender) {
			FileAppender fappender = (FileAppender) appender;
			if (fappender.getFile().startsWith("quartz")) {
				fappender.setFile(getPara(log));
				fappender.activateOptions();
			}
		}

	}

	// 设置模式切换日志路径
	private static void setModeLogPath() {
		String os = System.getProperty("os.name");
		String path = null;
		if (os.startsWith("Windows")) {
			path = "e:/mode.log";
		} else if (os.startsWith("Linux")) {
			path = "/var/log/messages";
		} else {
			path = "";
		}
		Appender appender = logger2.getAppender("mode");
		if (appender instanceof FileAppender) {
			FileAppender fappender = (FileAppender) appender;
			if (fappender.getFile().startsWith("mode")) {
				fappender.setFile(path);
				fappender.activateOptions();
			}
		}

	}

	public static int getPort() {
		return port;
	}

	public static void setPort(int port) {
		ServerSchedule.port = port;
	}

	public static int getSlave_port() {
		return port + 1;
	}
}
